#ifndef _AT24C04_H_
#define _AT24C04_H_

#include "stdint.h"
#include "swiic.h"

#ifdef __cplusplus
extern "C"
{
#endif

#define AT24C02 0
#define AT24C04 1
#define AT24C16 2
#define AT24C32 3
#define AT24C64 4
#define AT24C128 5
#define AT24C256 6
#define AT24C512 7

#ifndef AT24C_TYPE
#define AT24C_TYPE 5
#endif

#if AT24C02 == AT24C_TYPE
#define EEP_PAGE_SIZE 8
#define EEP_PAGE_MASK 0x07 
#define EEP_ADDR_SIZE 0x100
#define EEP_SUBA_SIZE 0x100
#define EEP_SUBA_MASK 0xFF
#define EEP_ADDR_TYPE 0 

#elif AT24C04 == AT24C_TYPE
#define EEP_PAGE_SIZE 16
#define EEP_PAGE_MASK 0x0F 
#define EEP_ADDR_SIZE 0x200
#define EEP_SUBA_SIZE 0x100
#define EEP_SUBA_MASK 0xFF
#define EEP_ADDR_TYPE 2 

#elif AT24C16 == AT24C_TYPE
#define EEP_PAGE_SIZE 16
#define EEP_PAGE_MASK 0x0F 
#define EEP_ADDR_SIZE 0x800
#define EEP_SUBA_SIZE 0x100
#define EEP_SUBA_MASK 0xFF
#define EEP_ADDR_TYPE 0x0E 

#elif AT24C32 == AT24C_TYPE
#define EEP_PAGE_SIZE 32
#define EEP_PAGE_MASK 0x1F 
#define EEP_ADDR_SIZE 0x1000
#define EEP_SUBA_SIZE 0x1000
#define EEP_SUBA_MASK 0x0FFF
#define EEP_ADDR_TYPE 0x01 

#elif AT24C64 == AT24C_TYPE
#define EEP_PAGE_SIZE 32
#define EEP_PAGE_MASK 0x1F 
#define EEP_ADDR_SIZE 0x2000
#define EEP_SUBA_SIZE 0x2000
#define EEP_SUBA_MASK 0x1FFF
#define EEP_ADDR_TYPE 0x01 

#elif AT24C128 == AT24C_TYPE
#define EEP_PAGE_SIZE 32
#define EEP_PAGE_MASK 0x1F 
#define EEP_ADDR_SIZE 0x4000
#define EEP_SUBA_SIZE 0x4000
#define EEP_SUBA_MASK 0x3FFF
#define EEP_ADDR_TYPE 0x01 

#elif AT24C256 == AT24C_TYPE
#define EEP_PAGE_SIZE 64
#define EEP_PAGE_MASK 0x3F 
#define EEP_ADDR_SIZE 0x8000
#define EEP_SUBA_SIZE 0x8000
#define EEP_SUBA_MASK 0x7FFF
#define EEP_ADDR_TYPE 1 

#elif AT24C512 == AT24C_TYPE
#define EEP_PAGE_SIZE 64
#define EEP_PAGE_MASK 0x3F	 
#define EEP_ADDR_SIZE 0x0000 
#define EEP_SUBA_SIZE 0x0000 
#define EEP_SUBA_MASK 0xFFFF
#define EEP_ADDR_TYPE 1 

#else
#error AT24 SEL ERROR
#endif

#define EEP_CHIP_ADDR 0xA0 

	typedef struct
	{
		uint8_t CHIP_ADDR;
		uint8_t ADDR_TYPE;
		uint16_t PAGE_SIZE;
		uint16_t PAGE_MASK;
		uint16_t ADDR_SIZE;
		uint16_t SUBA_SIZE;
		uint16_t SUBA_MASK;

		void (*start)(void);
		void (*stop)(void);
		sw_iic_ack_type (*snd_byte)(uint8_t dat); 
		uint8_t (*rcv_byte)(void);
		void (*ack_send)(sw_iic_ack_type);
	} at24c_cfg_type;

	const at24c_cfg_type *at24_hal_link(const at24c_cfg_type *hal);

	sw_iic_ack_type at24_write(uint16_t DataAdd, uint16_t Len, uint8_t *Rsc);

	sw_iic_ack_type at24_read(uint16_t DataAdd, uint16_t Len, uint8_t *Des);

	sw_iic_ack_type at24_multi_write(const at24c_cfg_type *at24c, uint16_t DataAdd, uint16_t Len, uint8_t *Rsc);

	sw_iic_ack_type at24_multi_read(const at24c_cfg_type *at24c, uint16_t DataAdd, uint16_t Len, uint8_t *Des);

#ifdef __cplusplus
}
#endif

#endif
